var QSDesktopClass = function(){
    var self = this;
    
    this.layout = function(){
        if (WorkspaceTabs) {
            WorkspaceTabs.setPanelOutSize(this.getDeskWidth(), this.getDeskHeight());
            if (WorkspaceTabs.currentTab.showHelper) {
                LayoutHelper.setOutSize(0, WorkspaceTabs.currentTab.panel.height()+23);
            }
            WorkspaceTabs.currentTab.windowGroup.refreshContainment();
        }
    }
    $(window).resize(function(){
        self.layout();
        workspaceManager.resizeMaxWindow();
    });
    
    this.getDeskWidth = function(){
        return $("body").width();
    }
    
    this.getDeskHeight = function(){
        return $("body").height() - ((Terminal.getConfig('HideTickerTape') == false) ? 88 : 36) - ((Terminal.getConfig('HideToolbar') == true||typeof(QS_DetachWorkspaceID) != "undefined")?0:22);
    }
    
    this.buildModules = function(configs, tab){ // build all components in one workspace.
        var module = null;
        var config = null;
        if (configs != null) {
            for (var i = 0; i < configs.length; i++) {
                config = configs[i];
                module = this.createModule(config, tab);
            }
        }
    };
    this.reBindMoudule = function(config,tab){ // update the components. delete the old widget and create a new widget.
        if(!tab||!tab.modules)return false;
        var win = tab.modules[config.id].win;
        if(win==null)return false;
        //push.proxy.unregister(win.widget);
        if (win.widget && typeof(win.widget.clear) == "function"){ // remove the component in window.
            GB_qsAutoCompleteBox.unSubscription(win._autoBoxID);
            win.widget.clear();
        }
        win.widget = null;  // remove the window.
        win.clear();
        this.createModule(config,tab);
    };
    this.createModule = function(config, tab){  //create one components in a workspace.
        tab = tab || WorkspaceTabs.currentTab;
        if (!QSPC.checkPermission(config.profile.type)) {
            return null;
        }
        var module = {
            win: this.createWidgetWindow(config, tab, config.profile.type),
            id: config.id,
            config: config
        }
        module.config.profile.name = module.config.profile.name || module.win.title;
        module.win.moduleId = module.id;
        
        if (!tab.modules) {
            tab.modules = {};
        }
        tab.modules[config.id] = module;
        
        return module;
    };
    
    this.addModule = function(profile){
        var config = {};
        config.id = idService.newMinusId();
        config.profile = profile;
        //add by yuntao
        if (profile.widget.ticker && profile.widget.ticker != null) {     
            profile.widget.mTicker=profile.widget.ticker;//add for chart.   
        }
        var module = this.createModule(config);
        if (module == null) 
            return module;

        var id = WorkspaceTabs.currentTab.id;
        if (!wsWidgets[id]) 
            wsWidgets[id] = [];
        wsWidgets[id].push(config);
        lastModules = WorkspaceTabs.currentTab.modules;
        //refreshWidgetList();
        return module;
    };
    
    this._removeWindow = function(win){
        push.proxy.unregister(win.widget);
        if (win.widget && typeof(win.widget.clear) == "function"){
            GB_qsAutoCompleteBox.unSubscription(win._autoBoxID);
            win.widget.clear();
        }
            
        win.widget = null;
        var ms = getCurrModules();
        if (ms[win.moduleId]) {
            if (win.moduleId > 0) {
                var id = WorkspaceTabs.currentTab.id;
                if (!wsWidgets[id].delIds) 
                    wsWidgets[id].delIds = [];
                wsWidgets[id].delIds.push(win.moduleId);
            }
            delete ms[win.moduleId];
        //refreshWidgetList();
        }
    };
    
    this.createWidgetWindow = function(config, workspace, type){ //widgetObj
        var self = this;
        var containerId = idService.newId();
        var html = '<div id="' + containerId + '">'+(this._hasWinMask[type]?'<div class="rtq-iframe-mask"></div>':'')+'</div>';
        var widget = null;
        var cfg = config.profile.widget || {};
        cfg.width = config.profile.w;
        cfg.height = config.profile.h;  
        if (config.profile.state == 2) {
            cfg.width = workspace.panel.width();
            cfg.height = workspace.panel.height();
        }
        var win = new Util.RtqWindow(workspace.panel, {
            windowReady: function(win){
                if(typeof QS_DetachWorkspaceID != 'undefined'){  // detach windown.
                    win.operatorEl.find(".close").hide();
                    win.operatorEl.find(".max").hide();
                    win.titleEl.unbind(".win"); // prevent restore.
                }
                win.setHtml(html);
                var winDropTarget = new Util.Dropable(win.contentEl, {
                    onDrop: function(e, proxy){
                        var ticker = proxy._ticker,component=proxy._component;
                        if (win.widget.type == 3 || win.widget.type == 9) { //qt //SR
                            win.QT_DropMask.hide();
                        }
                        if(proxy._secType==20){  // forex ticker only be droped in forex , watchlist, chart,k quote and CRT widgets.
                            if(win.widget.type!=11&&win.widget.type!=16&&win.widget.type!=0&&win.widget.type!=1&&win.widget.type!=10){
                                return;
                            }
                        }else{  // prvent no-forex to forex and CRT widget
                            if(win.widget.type==11||win.widget.type==16){
                                return;
                            }
                        }
                        if (win.widget.acceptTicker) {
							if (component == "screener") {
								win.widget.acceptTicker(ticker);
							}
							else {
								if ((win.widget.type == 0 || win.widget.type == 11 || win.widget.type == 16) && proxy._cpnId == config.id) { //prevent drop ticker from same window in Watchlist
									return;
								}
								else {
									win.widget.acceptTicker(ticker);
								}
							}
                        }
                    },
                    onEnter: function(e, proxy){
                        if (win.widget.type == 3 || win.widget.type == 9) { //qt
                            win.QT_DropMask.css({
                                width: win.cfg.width,
                                height: win.cfg.height
                            }).show();
                        }
                        if(proxy._secType==20){  // forex ticker only be droped in forex , watchlist, chart ,quote and CRT widgets.
                            if(win.widget.type!=11&&win.widget.type!=16&&win.widget.type!=0&&win.widget.type!=1&&win.widget.type!=10){
                                proxy.removeClass("rtq-dd-drop-yes");
                            }else{
                                proxy.addClass("rtq-dd-drop-yes");   
                            }
                        }else{  // prvent no-forex to forex and CRT widget
                            if(win.widget.type==11||win.widget.type==16){
                                proxy.removeClass("rtq-dd-drop-yes");
                            }else{
                                proxy.addClass("rtq-dd-drop-yes");
                            }
                        }
                    },
                    onOut: function(e, proxy){
                        if (win.widget.type == 3 || win.widget.type == 9) { //qt
                            win.QT_DropMask.hide();
                        }
                    }
                }, {
                    group: 'gridDDGroup'
                });
            },
            onResized: function(win, width, height){
                if (win.widget) {
                    win.widget.changeOutSize(width, height - 26);                    
                }                
            },
            beforeClosed: function(win){
                if(fileMenuObj!=null){
                    fileMenuObj.clear();
                }
                if (win.widget && win.widget.clearData) {
                    widget.clearData();
                }
                self._removeWindow(win);
            }
        }, {
            title: config.profile.name,
            width: config.profile.w,
            height: config.profile.h,
            top: config.profile.y,
            left: config.profile.x,
            locked:config.profile.locked,
            hasSettingPanel: true,
            closeAction: 'remove',
            dragContainment: workspace.panel,
            state: config.profile.state,
            layerIndex: config.profile.layerIndex,
            oldBox: config.profile.oldBox,
            active: config.profile.active,
            gridUnit:workspaceManager.getGridUnit(),
            dragMethod: 0,
            resizeOnDragStop:true,
//            minWidth:type==14?200:(type==10)?365:(config.profile.minWidth?config.profile.minWidth:255), ////for Quote and MarketWindow
//            minHeight:(type == 10)||(type==14)?97:(config.profile.minHeight?config.profile.minHeight:200)  //for Quote and MarketWindow
            minWidth:(type==10)?365:(config.profile.minWidth?config.profile.minWidth:255), ////for Quote and MarketWindow
            minHeight:(type == 10)?97:(config.profile.minHeight?config.profile.minHeight:200)  //for Quote and MarketWindow
        });
        workspace.windowGroup.register(win);
        
        if(type == 3 || type == 9){ //qt
            win.QT_DropMask = $('<div class="qt_dropmask"></div>').appendTo(win.contentEl);
        }

        //rewrite
        var oldSetTitle = win.setTitle;
        win.setTitle = function(til,ticker,cfg){
            if (til.substring(til.length - 1, til.length) == ":") {
                til=til.substring(0,til.length - 1) ;
            }
            var config={
                boxHide:false,
                needReplace:true
            };
            if(typeof cfg!='undefined'){
                $.extend(config,cfg);
            }
            if(typeof(win.searchBox)!="undefined"){
                win.searchBox.parent()[0].style.display="";
            }
            if(typeof(ticker)!="undefined"){
                if(til.substring(til.length-1,til.length)!=":"){
                    til+=":";
                }
                if(typeof(ticker)=="string"&&config.needReplace){
                    ticker=ticker.replace("/",".");
                }
            }
            oldSetTitle.call(win, til.length > 30 ? til.slice(0, 30) + '...' : til,ticker,cfg);
            if(typeof(win.searchBox)!="undefined"){
                if (config.boxHide) {
                    win.searchBox.parent()[0].style.display = "none";
                }else{
                    if (typeof(ticker) == "undefined" && !ticker) {
                        ticker='';
                    }
                    win.searchBox[0].value = ticker;
                }
            }
        };
        win.loadingEl = $('<div class="x-tool x-tool-loading" title="Loading"><img src="'+(QS_Theme=="black"?"//rtqimg.morningstar.com/theme/black/loading.gif":"//rtqimg.morningstar.com/img/loading.gif")+'" /> Loading...</div>').appendTo(win.el.find('div.win-hd'));
        win.showLoading = function(needToBeMasked){
            win.titleEl.find('h3').hide();
            win.loadingEl.width(win.cfg.width-win.operatorEl.width());
            win.loadingEl.show();           
            if(win.settingPanelObj){
                win.settingPanelObj.setDisabled();
            }
            if(typeof needToBeMasked!='undefined'&&needToBeMasked!='undefined'&&needToBeMasked==true){
                win.contentMask.show();
            }  
            win.el.addClass('rtq-win-onloading');             
        };
        win.hideLoading = function(){
            win.titleEl.find('h3').show();
            win.loadingEl.hide();
            if(win.settingPanelObj){
                win.settingPanelObj.setEnabled();
            }
            win.el.removeClass('rtq-win-onloading'); 
            win.contentMask.hide();  
        };        
        var fileMenuObj = null;
        
        
        if(typeof QS_DetachWorkspaceID == 'undefined'){  // not detach windown.
            if($.browser.msie && parseInt($.browser.version) == 7 && type != 1 && type !=0&& type !=14&& type !=3&& type !=9 ){
                /// ie 7
            }else{
                fileMenuObj = new componentFileMenu($(win.el.find('div.win-operator')),win,config,null,type);
            }
         }
        if(self._widgetHasSearch[type]){
            win.searchEl = $('<div class="win-autoComplete"><input type="text" value="" class="qs-ui-ipt ipt_symbol"/><a class="qs-ui-btn go lnk_symbol" href="javascript:void(0)">'+QS_Lang.workspace["tb_go"]+'</a></div>').appendTo(win.titleEl.find('h3'));//add for moving the autoComplete to title bar
            win.searchBox = $(win.searchEl.find(".ipt_symbol"));
            win.searchEl.show();
            $('h3',win.titleEl).css({//calculcate the width of the title
                //width:win.cfg.width - win.titleEl.find('div.win-operator').width() - 40
            });
            var ipt = win.titleEl.find('.ipt_symbol');
            win.titleEl.find('.lnk_symbol').click(function(e){
                GB_qsAutoCompleteBox.triggerACB(win._autoBoxID);
//              switch(type){
//                  case 0: win.widget.autoCPCallback(ipt.val());
//                  break;
//                  case 1: win.widget.acceptTicker(ipt.val());
//                  break;
//                  case 2: win.widget.acceptTicker(ipt.val());
//                  break;
//                  case 3: win.widget.acceptTicker(ipt.val());
//                  break;
//                  case 6: win.widget.addTicker(ipt.val());
//                  break;
//                  case 7: win.widget.addTicker(ipt.val());
//                  break;
//                  case 8: win.widget.addOptions(ipt.val());
//                  break;
//                  case 9: win.widget.addTicker(ipt.val());
//                  break;
//                  case 10:win.widget.addTicker(ipt.val());
//                  break;
//              };
            });
        }
        if(workspace.id>0){
            win.setToGrid(config);//added by wind 20101108
        }
        cfg.width = win.cfg.width;
        cfg.height = win.cfg.height;
        //the component width and height might be the same with the window component.
        widget = self._widgetClass[type].call(self, win, cfg, config.id, containerId, {
            type: type,
            id: config.id,
            __winObj: win,
            elId: containerId,
            containerId : containerId,
            hasSearch:self._widgetHasSearch[type],
            setTitle: function(til,tickter,cfg){
                win.setTitle(til,tickter,cfg);
            },
            getTitle: function(){
                return win.title;
            },
            showLoading: function(){
                win.showLoading((type==1||type==3||type==9)?false:true);
            },
            hideLoading: function(){
                win.hideLoading();
            },
            setWindowSize: function(w, h){
                //no one use it
                win.setSize(w, h);
            },
            maxmizeWindow: function(){
                win.maxmize();
            },
            openSearchDlg: function(){
                workspaceManager.openSearchDlg();
            },
            initAutoComplete:function(callback){// for adding the AutoComplete to title bar
                var idstr = (config.id<0)?'tmp_'+Math.abs(config.id):Math.abs(config.id);
                win._autoBoxID = 'autocpipt_'+idstr;
                //var downlistID = 'autocpddl_'+idstr;
                switch(type){
                    case 0: callback=function(data){
                        widget.autoCPCallback(data);
                    }
                    break;
                    case 1: callback=function(data){
                        widget.acceptTicker(data);
                    }
                    break;
                    case 2: callback = function(data){
                        widget.acceptTicker(data);
                    }
                    break;
                    case 3: callback=function(data){
                        widget.acceptTicker(data);
                    }
                    break;
                    case 6: callback = function(data){
                        widget.acceptTicker(data);
                    }
                    break;
                    case 7: callback =function(data){
                        widget.autoCPCallback(data);
                    }
                    break;
                    case 8:callback = function(data){
                        widget.autoCPCallback(data);
                    }
                    break;
                    case 9:callback =function(data){
                        widget.autoCPCallback(data);
                    }
                    break;
                    case 10:callback =function(data){
                        widget.acceptTicker(data);
//                        widget.autoCPCallback(data);
                    }
                    break;
		    case 20:callback =function(data){
                        widget.acceptTicker(data);
                    }
                    break;
					case 27:callback =function(data){
                        widget.acceptTicker(data);
                    }
                    break;
                };
                
                win.searchEl.find('.ipt_symbol').attr('id', win._autoBoxID);
             //   win.searchEl.find('.autocp_ddl').attr('id', downlistID);
                if ($("#"+win._autoBoxID).length < 1) {
                    return;
                }
               if(type==0){
                    GB_qsAutoCompleteBox.subscription(win._autoBoxID,callback,{needClear:true});
               }else{
                    GB_qsAutoCompleteBox.subscription(win._autoBoxID,callback);
               }
               
            }
        });
        win.widget = widget;                
        return win;     
    };
    
    this.WatchlistWindow = function(win, cfg, id, containerId, extend){
        var obj = new watchlist(QSPC.getConfig(0));
        //obj.__ObjPath = "push.proxy.getWatchlist(" + id + ")";
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(0);
        var settingPnCtn = win.settingPanelObj.getSettingPNctn();
		obj.init(containerId,cfg,{settingPnCtn:settingPnCtn});
        obj.ready();
        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
        win.settingPanelObj.onOpenSettingPN = obj.onOpenSettingPN;
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-wl');
        obj.changeOutSize(cfg.width, cfg.height - 27);
        return obj;
    };
    
    this.ChartWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_SecurityChartComponent(cfg.mTicker, "USA", "en-USA");
        $.extend(obj, extend);
        push.proxy.register(obj);
        var uiConfig=$.extend(true,{},QSPC.getConfig(1));  // deep copy.
        uiConfig.chartCtrl="rtqPanel";
        uiConfig.settingPanel=win.settingPanelObj.getSettingPNctn();
        obj.initOption(containerId,uiConfig,cfg,id);
        if (obj.hasSearch) {
            obj.initAutoComplete();
        }
	win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-cht');
        return obj;
    };
    
    this.NewsWindow = function(win, cfg, id, containerId, extend){
        var obj=new QS_News();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(2);
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-news');
        var extendCfg={
            type:cfg.type||cfg.model,
            height:cfg.height - 27,
			plusSymbol:(typeof(cfg.plusSymbol)!="undefined")?cfg.plusSymbol:true,
            settingContainer:$(win.settingPanelObj.getSettingPNctn())
        };
        var config=$.extend({},cfg,extendCfg);// here it will change the cfg. fix by yuntao
        //$.extend(cfg,extendCfg);
        obj.init(containerId, config, id);
        if (obj.hasSearch) {
            obj.initAutoComplete();
        }
        win.settingPanelObj.onOpenSettingPN = function(){
            obj.onOpenSettingPN();
        }
        return obj;
    };
 
    this.QtWindow = function(win, cfg, id, containerId, extend){
        var obj = new RTQ_Quicktake();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(3);
        obj.init(cfg, id, containerId, "", QSPC.getConfig(3));
        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-qkt');
        obj.changeOutSize(cfg.width, cfg.height);
        return obj;
    };
    
    this.L2MakerDepthWindow = function(win, cfg, id, containerId, extend){
        var obj = new RTQ_L2MarketDepth();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(6);
        var extendCfg={
            height:cfg.height-27,
            settingContainer:$(win.settingPanelObj.getSettingPNctn())
        }
        var config=$.extend({},cfg,extendCfg);// here it will change the cfg.
        //$.extend(cfg,extendCfg);
        obj.init(containerId, config, id);
        if (obj.hasSearch) {
            obj.initAutoComplete();
        }
        return obj;
    };
    
    this.TimeSalesWindow = function(win, cfg, id, containerId, extend){
        var obj = new RTQ_TimeSales();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(7);
        obj.initUIConfig({
            settingPanel: win.settingPanelObj.getSettingPNctn()
        });
		var extendCfg={
            height:cfg.height-27
		}
		var config=$.extend({},cfg,extendCfg);// here it will change the cfg.
        obj.init(containerId, "", config, id);
        return obj;
    };
    
    this.OptionsWindow = function(win, cfg, id, containerId, extend){
        var obj = new RTQ_Options();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(8);
        obj.init(containerId, '', cfg, id,{settingPanel:win.settingPanelObj.getSettingPNctn()});
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-opt');
        if (obj.hasSearch) {
            obj.initAutoComplete();
        }
        obj.changeOutSize(cfg.width, cfg.height-27);
        return obj;
    };
    
    this.SRWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_SecurityResearch();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(9);
        obj.settingPanel = win.settingPanelObj.getSettingPNctn();
        obj.init(containerId, cfg, id);
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-sr');
        obj.changeOutSize(cfg.width, cfg.height - 27);
        return obj;
    };
    
    this.QuotesWindow = function(win, cfg, id, containerId, extend){
        /*var obj = new RTQ_Quotes();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(10);
        obj.init(containerId, cfg, id);
        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
        win.settingPanelObj.onOpenSettingPN = function(){
            obj.onOpenSettingPN();
        }
        win.settingPanelObj.addClassToSettingPN('rtq-window-setpn-qts');        
        obj.changeOutSize(cfg.width, cfg.height-27);
        return obj;*/
        var settingContainer=$(win.settingPanelObj.getSettingPNctn());
        var quote_setting=new QuoteSettingPanel(settingContainer,{
            onClick:function(val,isSelected){
                if(isSelected){
                    obj.addDataPointByVal(val);
                }else{
                    obj.removeDataPointByVal(val);
                }
            },
            onClickAll:function(isSelected){
                if(isSelected){
                    obj.addAllDataPoints();
                }else{
                    obj.removeAllDataPoints();
                }
            }
        });
        if (cfg.height) {
            cfg.height = cfg.height - 27;
        }
        var obj=new QS.Quote($('#'+containerId),$.extend(cfg,{showNewsLink:false,showHead:false}),{
            onRemoveRow:function(id,row){
                quote_setting.selectDataPointChk([id], false);
                quote_setting.selectAllChkBtn(false);
            },
            afterInit: function(needResizeSetting){
                quote_setting.rebindData(obj.getDataPoints(),obj.getSequence());
                quote_setting.resize(null,null,needResizeSetting)
            },
            beforeClear:function(){
                quote_setting.clear();
            }
        });
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(10);
        if(cfg.ticker&&cfg.ticker!=''){
            obj.setTicker(cfg.ticker);
        }
        obj.init();
        if (obj.hasSearch) {
            obj.initAutoComplete();
        }
        win.settingPanelObj.onOpenSettingPN = function(){
            quote_setting.resize(137,150);
        }
        return obj;
    };

    
    this.ForexWindow = function(win, cfg, id, containerId, extend){
        var obj = new RTQ_Forex();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.tValidation = new tickerValidation(11);
        obj.init(containerId, cfg, id);
        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
        
        return obj;
    };
    this.CalendarWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_Calendar();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.init(containerId,cfg,id);
        return obj;
    };
    this.CommodityWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_Commodity();
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.init(containerId,cfg,id,cfg.width, cfg.height - 27);
        return obj;
    };

    this.MarketIdxWindow = function(win, cfg, id, containerId, extend){
        var obj = null;
        if(typeof(cfg["subType"])=="undefined"){  // compatable with the old version
            var name = win.cfg.title;
            if (name == "Commodity Futures") {
                cfg["subType"] = "14_6";
            } else if (name == "Market Indexes") {
                cfg["subType"] = "14_1"; 
            } else if(name == "Market Barometer"){
                cfg["subType"] = "14_2";
            }else if(name =="Sectors"){
                cfg["subType"] = "14_5";
            }else if(name == 'Bond Market'){
				cfg['subType'] = '14_4';
			}
        }
        cfg["isAPI"] = false;
        switch (cfg["subType"]) {
            case "14_1":
                obj = new QS_MarketIndex($.extend(true,cfg,{
                    menuList:["canada","ms","asian","european"],
                    gridColumns:["Symbol","Date","LastPrice","Chg%","Chg"]
                }));
                $.extend(obj, extend);
                push.proxy.register(obj);
                obj.setMenusName({
                    "canada":QS_Lang.marketindices["northamerican"],
                    "ms":QS_Lang.marketindices["ms"],
                    "asian":QS_Lang.marketindices["asian"],
                    "european":QS_Lang.marketindices["european"]
                });
                obj.init(containerId, id);
                break;
            case "14_2":
                obj = new QS_MarketBarometer();
                $.extend(obj, extend);
                cfg["clickable"] = false;
                push.proxy.register(obj);
                obj.init(containerId, cfg, id);
                break;
            case "14_5":
                obj = new QS_MarketSectors();
                $.extend(obj, extend);
                push.proxy.register(obj);
                obj.init(containerId, cfg, id);
                break;
            case "14_6":
                obj = new QS_MarketCommodityFutures();
                $.extend(obj, extend);
                push.proxy.register(obj);
                obj.init(containerId, cfg, id);
                break;
            case '14_4':   // bond 
                obj = new QS_MarketBondTerminal(containerId,cfg);
//				obj.id=id;
                $.extend(obj, extend);
                push.proxy.register(obj);
//                obj.init(containerId,cfg,id);
                break;
			default:break;
        }
        return obj;
    };
    this.SameStoreSalesWindow = function(win,cfg,id,containerid,extend){
        var obj=new QS_sameStoreSales();
        $.extend(obj,extend);
        push.proxy.register(obj);
        obj.init(containerid,cfg,id);
        return obj;
    };
    this.ExchangeActivity=function(win,cfg,id,containerid,extend){
        var pushObj=new QS_ExchangeActivity($("#"+containerid),$.extend(true,{isAPI:false,showSub:false}));
        pushObj.type ="18";
        pushObj.tValidation=new tickerValidation(18);
        push.proxy.register(pushObj);
        $.extend(pushObj,extend);
        pushObj.init();
        return pushObj;
    };
    this.ForexCRTWidow = function(win, cfg, id, containerId, extend){
        var pushObj = new QS_Forex_CRT_Push_Plugin();
        pushObj.type ="16";
        pushObj.id = id;
        push.proxy.register(pushObj);
        pushObj.setTickerValidation(new tickerValidation(16));
       // var historyObj = new QS_Forex_CRT_History_Plugin();
        var tipObj = new QS_Forex_CRT_Tip_Plugin(document.body);//win.toolPanel  to fix bug 508
        var settingPanel = new forexCRT_SettingPanel(null,{history:false,forwardList:[{"txt":"Spot","val":"spot"},{"txt":"Forward","val":"262"}],rateAble:false});
        var obj = new QS_Forex_CRT({dragAble:true},{"push":pushObj,"settingPanel":settingPanel,"tip":tipObj});
        $.extend(obj, extend);
       // push.proxy.register(obj);
        obj.init(containerId, cfg, id);
        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
        win.settingPanelObj.onOpenSettingPN = function(){
            obj.onOpenSettingPN();
        }
        return obj;
//      var pushObj = new QS_Forex_CRT_Push_Plugin();
//      
//      var historyObj = new QS_Forex_CRT_History_Plugin();
//        var obj = new QS_Forex_CRT(null,{"push":pushObj,"history":historyObj});
//        $.extend(obj, extend);
//        push.proxy.register(obj);
//        obj.tValidation = new tickerValidation(16, "", "tValidation");
//        obj.init(containerId, cfg, id);
//      //obj.setInterfaces("historicalDAO",new forexHistoricalData());
//        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
//        win.settingPanelObj.onOpenSettingPN = function(){
//            obj.onOpenSettingPN();
//        }
//        return obj;
    };
	
	this.SectorsWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_Sector($("#"+containerId),cfg);
		obj.id=id;
        $.extend(obj, extend);
		obj.init("ms","USA");
		
        push.proxy.register(obj);
		
		win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
		win.settingPanelObj.onOpenSettingPN = function(){
            obj.onOpenSettingPN();
        }

        return obj;
    };
	this.WorldMapWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_WorldMap($("#"+containerId));
		obj.id=id;
        $.extend(obj, extend);
        push.proxy.register(obj);
	   /*
        obj.init(containerId, cfg, id);
        

		*/
        return obj;
//      var pushObj = new QS_Forex_CRT_Push_Plugin();
//      
//      var historyObj = new QS_Forex_CRT_History_Plugin();
//        var obj = new QS_Forex_CRT(null,{"push":pushObj,"history":historyObj});
//        $.extend(obj, extend);
//        push.proxy.register(obj);
//        obj.tValidation = new tickerValidation(16, "", "tValidation");
//        obj.init(containerId, cfg, id);
//      //obj.setInterfaces("historicalDAO",new forexHistoricalData());
//        win.settingPanelObj.addtoSettingPN(obj.getSettingPanelDOM());
//        win.settingPanelObj.onOpenSettingPN = function(){
//            obj.onOpenSettingPN();
//        }
//        return obj;
    };
    this.GLAWindow=function(win, cfg, id, containerId, extend){
        /*var obj=new QS_GainerLoserActive($("#"+containerId),cfg);
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.init(cfg.exch);*/
        cfg.height=cfg.height-27;//27 is the height of the window-hd
        cfg.clickable=false;
        var obj=new QS_MarketGLA($("#"+containerId),cfg,{
            beforeClear:function(){
                objSetting.clear();
            }
        });
        $.extend(obj, extend);
        push.proxy.register(obj);
        obj.init();
        var settingContainer=$(win.settingPanelObj.getSettingPNctn());
        var objSetting=new GLASettingPanel(settingContainer,{
            country:obj.config.country,
            exchange:obj.config.exchange,
            type:obj.config.type
        },{
            onChangeExchange:function(country,exchange){
                obj.changeExchange(country,exchange);
            },
            onChangeType:function(type){
                obj.changeType(type);
            }
        });
        return obj;
    };
    this.HistoricalPriceWindow = function(win, cfg, id, containerId, extend){
        var obj = new QS_PriceTable($('#' + containerId), cfg.ticker, cfg);
	obj.addScrollPanel = true;
	obj.pageSize = 18;
        //var obj = new QS_PriceTable($('#' + containerId), "XNYS:IBM",cfg);
        $.extend(obj, extend);
        push.proxy.register(obj);
        //obj.tValidation = new tickerValidation(80,"obj","tValidation");
        obj.tValidation = new tickerValidation(80);
	obj.dataUrl = version.domain + "getHistoricalPrice.jsp?"; 
	obj.exportUrl = version.domain + "exportStockHistoricalToExcel.jsp?";	
	obj.afterAcceptTicker = function(t){
                    GB_qsAutoCompleteBox.setTicker(win._autoBoxID, {
                        ticker: t,
                        exch: "",
                        pid: ""
                    });
                }
        obj.init();
	if (obj.hasSearch) {
            obj.initAutoComplete();
        }
        return obj;
    };
	
	this.NewsOverviewWindow = function(win, cfg, id, containerId, extend){
		cfg.height=cfg.height-27;//27 is the height of the window-hd
	    var obj=new QS_OverviewNews($('#'+containerId),cfg,{
			onNewsClick:function(id,self){
				var profile = getDefaultProfileByType('2');
				profile.widget.symbolType='all';
				profile.widget.currentViewID=self.config.currentViewID;
				profile.widget.selectedContentID=id;
				RtqDesktop.addModule(profile);
			},
			onClickMore:function(self){
				var profile = getDefaultProfileByType('2');
				profile.widget.symbolType='all';
                profile.widget.currentViewID=self.config.currentViewID;
                RtqDesktop.addModule(profile);
			}
		});
        //$.extend(obj,extend);
        push.proxy.register(obj);
        return obj;
	};
	this.CalendarsOverviewWindow=function(win, cfg, id, containerId, extend){
        var obj = new QS_HomepageCalendars();
        $.extend(obj, extend);
		var profile={
			fixHeight:true,
			isAPI:false
		};
        push.proxy.register(obj);
        obj.init(containerId,$.extend(true,profile,cfg),id);
        return obj;
    };
    this.fairValueWindow=function(win, cfg, id, containerId, extend){        
        var obj = new QS_MktFairValue($('#'+containerId),cfg);
        push.proxy.register(obj);
        var settingContainer=$(win.settingPanelObj.getSettingPNctn());
        var fairvalue_setting=new FairValueSettingPanel(settingContainer,cfg,{
            onClick:function(val){
                obj.onTickerChange(val);
            }
        });        
        obj.changeOutSize(cfg.width, cfg.height - 27);
        return obj;
    };
    this._widgetClass = {
        0: this.WatchlistWindow,
        1: this.ChartWindow,
        2: this.NewsWindow,
        3: this.QtWindow,
        6: this.L2MakerDepthWindow,
        7: this.TimeSalesWindow,
        8: this.OptionsWindow,
        9: this.SRWindow,
        10:this.QuotesWindow,
        11:this.ForexWindow,
        12:this.CalendarWindow,
        13:this.CommodityWindow,
        14:this.MarketIdxWindow,
        15:this.SameStoreSalesWindow,
        16:this.ForexCRTWidow,
        17:this.MarketIdxWindow,//market barometer is 17 in before
        18:this.ExchangeActivity,
        19:this.GLAWindow,
		21:this.SectorsWindow,
		22:this.NewsOverviewWindow,
		23:this.CalendarsOverviewWindow,
		27:this.HistoricalPriceWindow,
        30:this.fairValueWindow
    };
    this._widgetHasSearch = {
        0: true,
        1: true,
        2: true,
        3: true,
        6: true,
        7: true,
        8: true,
        9: true,
        10:true,
        11:false,
        12:false,
        13:false,
        14:false,
        15:false,
        16:false,
        18:false,
        19:false,
		21:false,
		22:false,
		23:false,
		27:true,
        30:false
    };
    this._hasWinMask={
        3:true,
        9:true,
        14:true
    };
};

var componentFileMenu = function(container,win,config,extendMenuData,type){
    this.container = container;
    this.win = win;
    this.config = config;
    this.menuData = typeof this.config.detach!='undefined'&&!this.config.detach?[]:[{txt:QS_Lang.workspace["win_mdetach"],val:"detaching"}];//,{txt:"Detach (linked)",val:"zoomIn"}
    if ($.browser.msie && parseInt($.browser.version) == 7) {
        this.menuData = [];
    }
    this.extendMenuData = extendMenuData||[];
    this.El =null;
    this.menuObj = null;
    this.widgetType = type;
    this.fileMenuSynchronousShow= null;
    this.init();
    
};
componentFileMenu.prototype = {
    init:function(){
        var qslang=QS_Lang.workspace;
        if(this.widgetType==0||this.widgetType==15){// wl.
            //||this.widgetType==14 
            this.menuData.push({txt:qslang["win_mrefresh"],val:"refresh"});
        }
        if (this.widgetType == 0) {
            this.menuData.push({
                txt: qslang["win_mimport"],
                val: "",
                subMenu: [{
                    txt: qslang["win_mc&p"],
                    val: "import_manual"
                },{
                    txt: qslang["win_mupload"],
                    val: "excel"
                }]      
            });
            this.menuData.push({txt:qslang["win_mexport"],val:"export"});
        }
		
        // if(QSPC.checkPermission(20)){
        //     this.menuData.push({txt:qslang["win_mshare"],val:"share"});
        // }
		
        if(this.widgetType==1){               // chart.
            this.menuData.push({txt:qslang["win_mexport"],val:"export"});
            if (WorkspaceTabs.currentTab.id > 0) {//if default workspace,disabled capture features.
                this.menuData.push({
                    txt: qslang["win_mcapture"],
                    val: "capture"
                });
            }else{
                this.menuData.push({
                    txt: qslang["win_mcapture"],
                    val: "capture",
                    disable:true
                });
            }
        }else if(this.widgetType==7){  // Time and Sales.
            this.menuData.push({txt:qslang["win_mexport"],val:"export"});
        }else if(this.widgetType==3||this.widgetType==9){
            this.menuData.push({
                    txt: qslang["win_mreport"],
                    val: "idr"
            });
			if(QSPC.checkPermission(3.01)){
				this.menuData.push({
						txt: qslang["win_premmreport"],
						val: "premidr"
				});
			}
//          if($.browser.msie && parseInt($.browser.version) == 7){
//              this.menuData.push=[{txt: "Mstar Report",val: "idr"}];
//          }
            
        }
        if(this.extendMenuData.length>0){
            this.menuData = this.menuData.concat(this.extendMenuData);
        }
        this.El = $('<div class="file">'+qslang["win_mfile"]+'</div>');
        this.container.prepend(this.El);
        var sf  = this;
        this.El.unbind("mouseover.componentFileMenu").bind("mouseover.componentFileMenu",function(e){
            clearTimeout(sf.menuObj._timeOut);
            sf.El.addClass("file-on");
            sf.fileMenuSynchronousShow = setTimeout(function(){
                sf.menuObj.show();
                sf.menuObj.setPosition(sf.El.position().left+4,sf.El.parent().parent().height());
            },200);
        }).unbind("mouseleave.componentFileMenu").bind("mouseout.componentFileMenu",function(e){
            if($(e.relatedTarget).prop("class").indexOf("rtq-menu")==-1){
                sf.El.removeClass("file-on");
                sf.menuObj.menu.css("border-top",0)
                sf.menuObj.hide(200);
                clearTimeout(sf.fileMenuSynchronousShow);
            }
        });
        if (this.menuData.length) { // has menu data.
            this.menuObj = new Util.CascadeMenu(this.win.toolPanel, {
                display: false,
                autoHide: true,
                isTraceMouse: true,
                fixedDirection: false
            }, this.menuData,{
                onHide:function(){
                    if(typeof(sf.El)!="undefined"){
                        sf.El.removeClass("file-on");
                    }
                },
                onClick:function(data){
                    var val = data.data.val;
                    if (val == "detaching"|| val == "zoomIn") {
                        sf._menuCallDetaching(val);
                    }else if(val=="share"){
                        if(QS_MessageSender==null) QS_MessageSender=new MessageSender();
    					var wsid=WorkspaceTabs.currentTab.id,widget=getDefaultProfileByType(sf.widgetType);
                        QS_MessageSender.open("widget",wsid,sf.win.moduleId,widget.name);
                    }else if(val=="capture"){
                        sf._menuCallCapturing(val);
                //  }else if(val=="excel"){
                //      Qs_ExcelImportDialog.openWin(sf.win.widget);
                //  }else if(val=="import"){
                //      Qs_ManualImportDialog.open(sf.win.widget);
                    }else{
                        if(sf.win.widget&&typeof(sf.win.widget.fileMenuCallback)=="function"){
                            sf.win.widget.fileMenuCallback(val);
                        }else if(typeof sf.win.fileMenuCallback == "function"){//for global window
                            sf.win.fileMenuCallback(val);
                        }
                    }
                    sf.menuObj.hide();
                }
                
                
            });
            
            var captureEL = this.menuObj.getItemByVal('capture');
            if(captureEL){
                Util.addBetaTip(captureEL.el.children('a')); 
            }
        } 
    },
    _menuCallCapturing:function(val){
        var config = this.config,self=this;
        var workspaceId = WorkspaceTabs.currentTab.id,
            componentId = config.id;
        if (workspaceId > 0) { // component not be saved.
            workspaceManager.openScreenshotDialog();
            workspaceManager.saveWorkspace(WorkspaceTabs.currentTab, false, false, function(){
                componentId = WorkspaceTabs.currentTab.windowGroup.curWin.moduleId;
                DBHelper.captureComponent(workspaceId, componentId, self.widgetType, function(o){
                    o = $.evalJSON(o);
                    if (o && o.screenShotURL) {
                        workspaceManager.setScreenshotImg(o.screenShotURL);
                    }
                });
            });
        }
        //workspaceManager.openScreenshotDialog(this.config.profile.w+20,this.config.profile.h+40,'');  
    },
   /* _menuCallDetaching:function(val){
        var config = this.config;
        var w = 800, h = 600, workspaceId = WorkspaceTabs.currentTab.id, componentId = config.id;
        if (workspaceId > 0 && componentId < 0) { // component not be saved.
            workspaceManager.saveWorkspace(WorkspaceTabs.currentTab, false, false, function(){
                componentId = WorkspaceTabs.currentTab.windowGroup.curWin.moduleId;
                var name = val=="zoomIn"?componentId:new Date().getTime();
                QS_DetachWindows[componentId] = window.open('detaching.jsp?wid=' + workspaceId + '&cid=' + componentId+'&type='+val, 'QuoteSpeed' + name, 'width=' + w + ',height=' + h + ',top=' + (screen.height - h - 50) / 2 + ',left=' + (screen.width - w) / 2 + ',fullscreen=no,location=no,toolbar=no,menubar=no');
                if (window.focus) {
                    QS_DetachWindows[componentId].focus();
                }
                if(val=="zoomIn"){
                    WorkspaceTabs.currentTab.modules[componentId].win.disable();
                }  
            });
        } else {
            var cwin = WorkspaceTabs.currentTab.modules[componentId].win;
            if(workspaceId<0){ // default workspace save the components which will be detached.
                if(cwin.widget&&typeof(cwin.widget.saveConfig)=="function"){ 
                    QS_DefaultWsDetachWidgets[componentId] = cwin.widget.saveConfig();
                }
            }
            var name = val=="zoomIn"?componentId:new Date().getTime();
            QS_DetachWindows[componentId] = window.open('detaching.jsp?wid=' + WorkspaceTabs.currentTab.id + '&cid=' + config.id+'&type='+val, 'QuoteSpeed' + name, 'width=' + w + ',height=' + h + ',top=' + (screen.height - h - 50) / 2 + ',left=' + (screen.width - w) / 2 + ',fullscreen=no,location=no,toolbar=no,menubar=no');
            if (window.focus) {
                QS_DetachWindows[componentId].focus();
            }
            if (val == "zoomIn") {
                cwin.disable();
            }
            return false;
        }
    },
	*/
        _menuCallDetaching:function(val){
        var config = this.config;
        var w = 800, h = 600, workspaceId = WorkspaceTabs.currentTab.id, componentId = config.id;
        if (workspaceId > 0) { // component not be saved.
            workspaceManager.saveWorkspace(WorkspaceTabs.currentTab, false, false, function(){
                componentId = WorkspaceTabs.currentTab.windowGroup.curWin.moduleId;
                var name = val=="zoomIn"?componentId:new Date().getTime();
                QS_DetachWindows[componentId] = window.open('detaching.jsp?wid=' + workspaceId + '&cid=' + componentId+'&type='+val, 'QuoteSpeed' + name, 'width=' + w + ',height=' + h + ',top=' + (screen.height - h - 50) / 2 + ',left=' + (screen.width - w) / 2 + ',fullscreen=no,location=no,toolbar=no,menubar=no');
                if (typeof QS_DetachWindows[componentId].focus == 'function') {
                    QS_DetachWindows[componentId].focus();
                }
                if(val=="zoomIn"){
                    WorkspaceTabs.currentTab.modules[componentId].win.disable();
                }  
            });
        } else {
			if(workspaceId<100){
				Util.message(QS_Lang.text["saveworkspacefirst"]);
				return false;
			}
            var cwin = WorkspaceTabs.currentTab.modules[componentId].win;
            //if(workspaceId<0){ // default workspace save the components which will be detached.
			if(cwin.widget&&typeof(cwin.widget.saveConfig)=="function"){ 
				QS_DefaultWsDetachWidgets[componentId] = cwin.widget.saveConfig();
			}
            //}
            var name = val=="zoomIn"?componentId:new Date().getTime();
            QS_DetachWindows[componentId] = window.open('detaching.jsp?wid=' + WorkspaceTabs.currentTab.id + '&cid=' + config.id+'&type='+val, 'QuoteSpeed' + name, 'width=' + w + ',height=' + h + ',top=' + (screen.height - h - 50) / 2 + ',left=' + (screen.width - w) / 2 + ',fullscreen=no,location=no,toolbar=no,menubar=no');
            if (window.focus) {
                QS_DetachWindows[componentId].focus();
            }
            if (val == "zoomIn") {
                cwin.disable();
            }
            return false;
        }
    },
    show:function(){
        
    },
    hide:function(){
        
    },
    clear:function(){
        this.El.unbind(".componentFileMenu");
        for(var p in this){
            if(!p || p == 'clear'){continue;}
            this[p] = null;
            delete this[p];
        }
    }
}
